package java_util.coo_util.Log;


import java_util.interfaceType.I_Log;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;


public class C_Log {

    public static String o_tag = "tagNull";
    public static I_Log o_logObj;

    public static void error(String message) {
        if (message == null || "".equals(message)) {
            return;
        }
        S_Log(E_LogType.e0_Error, o_tag, time(), message, S_GetInfo(2));
    }

    public static void info(Object log) {
        if (log == null) {
            return;
        }
        S_Log(E_LogType.e3_Log, o_tag, time(), log.toString(), S_GetInfo(2));
    }

    public static void Log(String message) {
        if (message == null || "".equals(message)) {
            return;
        }
        S_Log(E_LogType.e3_Log, o_tag, time(), message, S_GetInfo(2));
    }

    public static void LogFormat(String format, Object... args) {
        String message = null;
        if (args.length == 0) {
            message = format;
        } else {
            message = String.format(format, args);
        }
        S_Log(E_LogType.e3_Log, o_tag, time(), message, S_GetInfo(2));
    }

    public static void LogError(String message) {
        if (message == null || "".equals(message)) {
            return;
        }
        S_Log(E_LogType.e0_Error, o_tag, time(), message, S_GetInfo(2));
    }

    public static void LogError(String message, Exception ex) {
        String message0 = message + "_____getMessage==" + ex.getMessage() + "\nStackTrace==" + S_GetInfo(ex, 0);
        S_Log(E_LogType.e0_Error, o_tag, time(), message0, S_GetInfo(2));
    }

    public static void LogErrorFormat(String format, Object... args) {
        if (o_logObj != null) {
            String message = null;
            if (args.length == 0) {
                message = format;
            } else {
                message = String.format(format, args);
            }
            S_Log(E_LogType.e0_Error, o_tag, time(), message, S_GetInfo(2));
        } else {
            System_Log(E_LogType.e0_Error, String.format(format, args));
        }
    }

    public static void LogErrorInfo(String message, String stackTrace, boolean isAddStackTrace) {
        S_Log(E_LogType.e0_Error, o_tag, time(), message, stackTrace);
    }

    public static void LogErrorInfo(String message, Exception ex, boolean isAddStackTrace) {
        String stackTrace = S_GetInfo(ex);
        S_Log(E_LogType.e0_Error, o_tag, time(), message, stackTrace);
    }

    public static void LogWarning(String message) {
        if (message == null || "".equals(message)) {
            return;
        }
        S_Log(E_LogType.e2_Warning, o_tag, time(), message, S_GetInfo(2));
    }

    public static void LogWarningFormat(String format, Object... args) {
        String message = null;
        if (args.length == 0) {
            message = format;
        } else {
            message = String.format(format, args);
        }
        S_Log(E_LogType.e2_Warning, o_tag, time(), message, S_GetInfo(2));
    }


    public static void LogException(String message, Exception exception) {
        S_Log(E_LogType.e0_Error, o_tag, time(), message + "__" + exception.getMessage(), S_GetInfo(exception, 0));
    }


    public static void S_Log(int type, String tag, String time, String log, String stackTrace) {
        if (o_logObj != null) {
            o_logObj.S_Log(type, tag, time, log, stackTrace);
        } else {
            System_Log(type, log + "\n.." + stackTrace);
        }
    }

    static void System_Log(int type, String log) {
        switch (type) {
            case E_LogType.e0_Error:
                System.out.println("\033[01;31m" + log + "\033[0m");
                break;
            case E_LogType.e1_Assert:
                System.out.println("\033[32m" + log + "\033[0m");
                break;
            case E_LogType.e2_Warning:
                System.out.println("\033[01;33m" + log + "\033[0m");
                break;
            case E_LogType.e3_Log:
                System.out.println("\033[32m" + log + "\033[0m");
                break;
            case E_LogType.e4_Exception:
                System.out.println("\033[32m" + log + "\033[0m");
                break;
        }

    }

    public static String S_GetInfo(Exception ex) {
        return S_GetInfo(ex, "", 0, "");
    }

    public static String S_GetInfo(Exception ex, String message) {
        return S_GetInfo(ex, message, 0, "");
    }

    public static String S_GetInfo(Exception ex, String message, int shieldLine) {
        return S_GetInfo(ex, message, shieldLine, "");
    }

    public static String S_GetInfo(Exception ex, String message, int shieldLine, String end) {
        StackTraceElement[] st = new Exception().getStackTrace();
        String message1 = String.format("%s...%s", message, ex.getMessage());
        return S_GetInfo(message1, st, shieldLine, end);
    }

    public static String S_GetInfo(String message, StackTraceElement[] st, int ShieldLine) {
        return S_GetInfo(message, st, ShieldLine, "");
    }

    public static String S_GetInfo(String message, StackTraceElement[] stack, int ShieldLine, String end) {
        if (stack == null) {
            stack = new Exception().getStackTrace();
        }
        StringBuilder ssb = new StringBuilder(message + "\n");
        for (int i = ShieldLine; i < stack.length; i++) {
            String fileName = stack[i].getMethodName();
            if (Objects.equals(fileName, "")) {
                continue;
            }
            StackTraceElement ss = stack[i];
            ssb.append(System.getProperty("user.dir"));
            ssb.append("___ ");
            ssb.append(ss.getClassName());
            ssb.append("/__ ");
            ssb.append(ss.getMethodName());
            ssb.append("(.)__ ");
            ssb.append(ss.getLineNumber());
            ssb.append("\n");
        }
        return ssb.toString();
    }


    public static String S_GetInfo(int startIndex) {
        return S_GetInfo(new Exception(), startIndex);
    }

    public static String S_GetInfo(Exception ex, int ShieldLine) {
        bb.setLength(0);
        StackTraceElement[] stack = ex.getStackTrace();
        for (int i = ShieldLine; i < stack.length; i++) {
            if (stack[i] == null) {  continue; }
            bb.append(stack[i].getClassName()).append("__").append(stack[i].getMethodName());
            bb.append("___.(").append(stack[i].getFileName()).append(":").append(stack[i].getLineNumber()).append(")\n");
        }
        return bb.toString();
    }

    static StringBuilder bb = new StringBuilder();

    static Date date;

    static String time() {
        date = new Date();
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    }
}
